package com.itheima.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.constant.RedisConstant;
import com.itheima.entity.PageResult;
import com.itheima.entity.QueryPageBean;
import com.itheima.mapper.OrderMapper;
import com.itheima.mapper.SetmealMapper;
import com.itheima.pojo.Setmeal;
import com.itheima.service.SetmealService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import redis.clients.jedis.JedisPool;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service(interfaceClass = SetmealService.class)
@Transactional
public class SetmealServiceImpl implements SetmealService {

   @Autowired
   private SetmealMapper setmealMapper;
   @Autowired
   private OrderMapper orderMapper;
   @Autowired
   private JedisPool jedisPool;
   @Autowired
   private FreeMarkerConfigurer freeMarkerConfigurer;
   @Value("${out_put_path}")
   private String outPutPath;//通过spring引入的配置文件中的值

   //添加套餐信息
   public void add(Setmeal setmeal, Integer[] checkGroupIds) {
      //1.插入套餐信息
      setmealMapper.addSetmeal(setmeal);

      //2.插入套餐和检查组关系数据
      //2.1获取生成的套餐id
      Integer setmealId = setmeal.getId();
      //调用批量插入方法
      batchInsert(checkGroupIds, setmealId);

      //3.插入成功后,将套餐的图片名字存入redis中
      jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_DB_RESOURCES, setmeal.getImg());

      //4.新增套餐后,重新生成静态页面
      generateMobileStaticHtml();
   }

   //生成移动端静态页面方法
   private void generateMobileStaticHtml() {
      //1.查询数据库获取所有套餐信息
      List<Setmeal> setmealList = this.getSetmealAll();
      //2.生成套餐列表静态页面
      generateSetmealListStaticHtml(setmealList);
      //3.生成套餐详情静态页面
      generateSetmealDetailStaticHtml(setmealList);
   }

   //生成套餐详情静态页面的方法
   private void generateSetmealDetailStaticHtml(List<Setmeal> setmealList) {
      //1.处理参数
      Map<String, Object> map = null;
      //1.1遍历集合
      for (Setmeal setmeal : setmealList) {
         //1.2调用方法获取每个详情页面的具体信息
         Setmeal setmealDetail = this.findById(setmeal.getId());
         //1.3封装map
         map = new HashMap<String, Object>();
         map.put("setmeal",setmealDetail);

         //2.将每个详情页生成静态页面
         generateHtml("mobile_setmeal_detail.ftl","setmeal_detail_"+setmeal.getId()+".html",map);
      }

   }

   //生成套餐列表静态页面的方法
   private void generateSetmealListStaticHtml(List<Setmeal> setmealList) {
      //1.处理参数
      Map<String, Object> map = new HashMap<String, Object>();
      map.put("setmealList",setmealList);
      //2.生成静态页面
      generateHtml("mobile_setmeal.ftl", "m_setmeal.html", map);
   }

   //通用:生成静态页面方法
   private void generateHtml(String templateName,String htmlPageName,Map map) {
      //1.创建配置freemarker配置对象
      Configuration configuration = freeMarkerConfigurer.getConfiguration();

      try {
         //2.创建模板对象
         Template template = configuration.getTemplate(templateName);
         //3.准备参数
         File file = new File(outPutPath+"/"+htmlPageName);
         BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"));

         //4.使用模板对象执行操作
         template.process(map,out);
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

   //分页查询
   public PageResult findPage(QueryPageBean queryPageBean) {
      //1.获取参数
      Integer currentPage = queryPageBean.getCurrentPage();
      Integer pageSize = queryPageBean.getPageSize();
      String queryString = queryPageBean.getQueryString();
      //2.使用分页助手
      PageHelper.startPage(currentPage, pageSize);

      //3.执行条件查询
      Page<Setmeal> page = setmealMapper.findByCondition(queryString);

      //4.返回结果
      return new PageResult(page.getTotal(), page.getResult());
   }

   //获取所有套餐信息
   public List<Setmeal> getSetmealAll() {
      Page<Setmeal> page = setmealMapper.findByCondition("");
      List<Setmeal> list = page.getResult();
      return list;
   }

   //根据id查询所有套餐数据,同时查询出对应检查组,和对应检查项
   public Setmeal findById(Integer setmealId) {
      Setmeal setmeal = setmealMapper.findById(setmealId);
      return setmeal;
   }

   //统计套餐就诊的人数
   public List<Map<String, Object>> getSetmealCount() {
      List<Map<String, Object>> list = setmealMapper.getSetmealCount();
      return list;
   }

   /**
    * 查询热门套餐,取预约占比前二套餐
    * @return 参数包含:套餐名,套餐预约数量,预约占比,取
    */
   public List<Map<String, Object>> findHotSetmeal() {
      //1.查询预约占比前二的套餐
      List<Map<String, Object>> list = setmealMapper.findHostTop4Setmeal();
      return list;
   }

   //批量插入关系表数据
   private void batchInsert(Integer[] checkGroupIds, Integer setmealId) {
      if (checkGroupIds != null && checkGroupIds.length > 0) {
         //2.2封装关系集合,用于批量插入
         List<Map<String, Integer>> list = new ArrayList<Map<String, Integer>>();
         Map<String, Integer> map = null; //将变量声明在循环外节约栈内存
         for (Integer checkGroupId : checkGroupIds) {
            //2.2.1封装每一对套餐和检查组关系到map中
            map = new HashMap<String, Integer>();
            map.put("setmealId", setmealId);
            map.put("checkGroupId", checkGroupId);

            //2.2.2添加map到list中
            list.add(map);
         }
         //2.3批量插入关系
         setmealMapper.addSetmealAndCheckGroupRelation(list);
      }
   }
}
